package main

import (
	"fmt"
	"reflect"
)

type Student struct {
	Name  string  `json:"name"`
	Age   int     `json:"age"`
	Score float64 `json:"score"`
	Sex   string
}

func (stu *Student) GetName() string {
	return stu.Name
}

func (stu *Student) GetSum(a int, b int) int {
	return stu.Age + a + b
}

func (stu *Student) UpdateStu(name string, age int, score float64) {
	stu.Name = name
	stu.Age = age
	stu.Score = score
}

func testStudent(n interface{}) {
	rType := reflect.TypeOf(n)

	rValue := reflect.ValueOf(n)
	fmt.Println("-----属性操作-----")
	for i := 0; i < rValue.Elem().NumField(); i++ {
		v := rValue.Elem().Field(i)
		field := rType.Elem().Field(i)
		fieldType := field.Type
		tag := field.Tag
		fmt.Printf("属性类型%s ,属性名称%s,属性值 %v, json 标签 %s\n", fieldType.Name(), field.Name, v, tag.Get("json"))
	}

	rValue.Elem().Field(0).SetString("李四")

	fmt.Println("-----方法操作-----")
	numMethod := rValue.NumMethod()
	fmt.Println("一共有", numMethod, "个方法")
	for i := 0; i < numMethod; i++ {
		method := rType.Method(i)
		fmt.Println("type", method.Name, method.Func.String(), method.Index)
	}
	callResult := rValue.Method(0).Call(nil)
	for _, result := range callResult {
		fmt.Println(result)
	}
	callResult = rValue.Method(1).Call([]reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2)})
	for _, result := range callResult {
		i := result.Interface()
		i2, ok := i.(int)
		if ok {
			fmt.Println(i2)
		}
	}
	callResult = rValue.Method(2).Call([]reflect.Value{reflect.ValueOf("李四"), reflect.ValueOf(12), reflect.ValueOf(123.22)})
	if callResult == nil {
		fmt.Println("第三个方法没有返回值")
	}
}

func testReflect() {
	stu := Student{
		Name:  "张三",
		Age:   24,
		Score: 22.1,
	}
	testStudent(&stu)
	fmt.Println(stu)
}
